<script setup lang="ts">
import { onBeforeMount, Ref, ref } from 'vue'
import {
    CheckboxType,
    ColorType,
    ContainerType,
    InputNumberType,
    InputType,
    PasswordType,
    RadioType,
    RateType,
    SelectType,
    SliderType,
    SwitchType,
    TextareaType,
    TimePickerType,
    TimeSelectType,
    VirtualizedSelectType,
} from '../../types/ItemMetaTypes'
import useStore from '../../store'
import ItemResolve from './ItemsResolve.vue'
import { FormItemsEnum } from '../../store/modules/FormItems'

interface PropsType {
    height?: string
    preview?: boolean
    formData: object
    formConfig?: object
    formItems: Array<
        | CheckboxType
        | ContainerType
        | InputType
        | PasswordType
        | TextareaType
        | InputNumberType
        | RadioType
        | RateType
        | SwitchType
        | SliderType
        | ColorType
        | SelectType
        | VirtualizedSelectType
        | TimePickerType
        | TimeSelectType
    >
}

// 定义props
// eslint-disable-next-line no-undef
const props = withDefaults(defineProps<PropsType>(), {
    height: '96.8vh',
    preview: true,
    // @ts-ignore
    formConfig: useStore.state.FormConfig,
})

const dynamicForm: Ref<null | HTMLElement> = ref<null | HTMLElement>(null)

// 初始化表单的特殊字段双向绑定属性
const initItemData = (e: any): void => {
    // @ts-ignore
    // eslint-disable-next-line vue/no-mutating-props
    props.formData[e.key] = e.value
    if (!e.key) {
        return
    }
    // 移除原先存在的key
    let keys: Array<string> = e.key.split('_')
    if (!keys || keys.length !== 2) {
        return
    }
    // @ts-ignore
    delete props.formData[keys[0]]
}

// 添加时触发
const onAdd = (original: any): void => {
    let { newIndex } = original
    if (newIndex === props.formItems.length) {
        // 加在最后边的情况下需要-1
        newIndex -= 1
    }
    useStore.dispatch(FormItemsEnum.ModuleFunctionName(FormItemsEnum.ADD_FORM_ITEM), newIndex)
}

// eslint-disable-next-line no-undef
const emit = defineEmits(['selectItem', 'submit'])

// 点击控件时触发
const selectCurrent = (item: any): void => {
    props.formItems.forEach((e) => {
        e.selectCurrent = false
        if (e.type === 'Container') {
            // @ts-ignore
            e.cols.forEach((e1) => e1.formItems.forEach((e2) => (e2.selectCurrent = false)))
        }
    })
    if (props.preview) {
        return
    }
    item.selectCurrent = true
    useStore.dispatch(FormItemsEnum.ModuleFunctionName(FormItemsEnum.SET_CURRENT_ITEM), item)
    emit('selectItem', item)
}
// 在挂载前判断是否是预览模式，预览初始化状态
onBeforeMount(() => {
    if (props.preview) {
        props.formItems.forEach((e) => {
            e.selectCurrent = false
            if (e.type === 'Container') {
                // @ts-ignore
                e.cols.forEach((e1) => e1.formItems.forEach((e2) => (e2.selectCurrent = false)))
            }
        })
    }
})

// 触发事件删除
const deleteItem = (i: number) => {
    useStore.dispatch(FormItemsEnum.ModuleFunctionName(FormItemsEnum.REMOVE_FORM_ITEM), i)
    useStore.dispatch(FormItemsEnum.ModuleFunctionName(FormItemsEnum.SET_CURRENT_ITEM), {})
}

// 触发事件复制
const copyItem = (i: number) => {
    useStore.dispatch(FormItemsEnum.ModuleFunctionName(FormItemsEnum.COPY_FORM_ITEM), i)
}

// 提交
const submit = (): void => {
    emit('submit')
}

// eslint-disable-next-line no-undef
defineExpose({
    dynamicForm,
})
</script>

<template>
    <el-form
        ref="dynamicForm"
        :model="formData"
        :size="formConfig.size"
        :inline="formConfig.inline"
        :disabled="formConfig.disabled"
        :show-message="formConfig.showMessage"
        :label-position="formConfig.labelPosition"
        :label-width="formConfig.labelWidth + 'px'"
        :hide-required-asterisk="formConfig.hideRequiredAsterisk"
    >
        <draggable
            group="people"
            :list="formItems"
            :style="preview ? {} : { height: `calc(${height} - 40px)` }"
            :disabled="preview"
            :animation="300"
            @add="onAdd"
        >
            <ItemResolve
                v-for="(item, i) in formItems"
                @click="selectCurrent(item)"
                :formItem="item"
                :preview="preview"
                :formData="formData"
                :key="item.modelValue"
                :dynamicForm="dynamicForm"
                @submit="submit"
                @copyItem="copyItem(i)"
                @deleteItem="deleteItem(i)"
                @initItemData="initItemData"
            />
            <div style="height: 10px"></div>
        </draggable>
    </el-form>
</template>

<style scoped></style>
